﻿Imports System.Collections
Public Class Tablero
#Region "variables"

    Private tablero(8, 8) As Celda

    Private contadorCaballoNegro As Boolean
    Private contadorCaballoBlanco As Byte

    Private fila() As String = {"", "8", "7", "6", "5", "4", "3", "2", "1"}
    Private columna() As String = {"", "a", "b", "c", "d", "e", "f", "g", "h"}

#End Region

#Region "Constructor"
    'Te pone los contadores en 0 y te crea la matriz
    Public Sub New()
        'MyBase.New() siempre debe estar en el constructor
        MyBase.New()
        Constructor()
        contadorCaballoBlanco = 0
        ContadorCaballoNegro1 = False

    End Sub
    Public Sub New(ByVal tab As Tablero)
        MyBase.New()
        contadorCaballoBlanco = tab.contadorCaballoBlanco
        contadorCaballoNegro = tab.contadorCaballoNegro
        Constructor()

        For index As Integer = 1 To 8
            For j As Integer = 1 To 8
                tablero(index, j).figura = tab.obtenerFigura(index, j)

            Next
        Next
    End Sub
    Private Sub Constructor()
        For i As Integer = 1 To 8
            For j As Integer = 1 To 8
                tablero(i, j) = New Celda(columna(i) + fila(j))
                tablero(i, j).posicionx = i 'Columna
                tablero(i, j).posicionY = j 'Fila
                tablero(i, j).posicionXY = CStr(i) + CStr(j)
                tablero(i, j).figura = piezas.vacio
            Next
        Next
    End Sub

#End Region

#Region "metodos"
    'Obtiene el nombre de la celda de acuerdo al nombre de los indices
    Public Overloads Function obtenerPosicion(ByVal fil As Integer, ByVal col As Integer) As String
        Return tablero(fil, col).celda

    End Function
    Public Overloads Function obtenerPosicion(ByVal posXY As Integer) As String
        Dim i, j As Integer
        i = CInt(posXY) \ 10
        j = CInt(posXY) Mod 10
        Return tablero(i, j).celda
    End Function
    'Obtiene la figura que se encuentra en la posición requerida ("blanco", "negro", "")
    Public Overloads Function obtenerFigura(ByVal i As Integer, ByVal j As Integer) As String
        Return tablero(i, j).figura
    End Function
    Public Overloads Function obtenerFigura(ByVal posXY As Integer) As String
        Dim i, j As Integer
        i = CInt(posXY) \ 10
        j = CInt(posXY) Mod 10
        Return tablero(i, j).figura
    End Function

    'Va a contar los caballos blancos a medida que se los va agregando
    Public Overloads Sub Contador()
        If contadorCaballoBlanco < 64 Then
            contadorCaballoBlanco = contadorCaballoBlanco + 1
        End If

    End Sub
    'Va a sumar la cantidad de caballos blancos que se generen aleatoriamente
    Public Overloads Sub Contador(ByVal incremento As Byte)
        If incremento < 64 And (contadorCaballoBlanco + incremento) < 64 Then
            contadorCaballoBlanco = contadorCaballoBlanco + incremento
        End If
    End Sub
    'Descuenta a medida que se van eliminando los caballos blancos
    Public Overloads Sub DesContador()
        If contadorCaballoBlanco > 0 Then
            contadorCaballoBlanco = contadorCaballoBlanco - 1
        End If
    End Sub
    Public Overloads Sub DesContador(ByVal tab As Tablero)
        If tab.contadorCaballoBlanco > 0 Then
            tab.contadorCaballoBlanco = contadorCaballoBlanco - 1
        End If
    End Sub
    Public Overloads Sub DesContador(ByVal decremento As Byte)
        If contadorCaballoBlanco > 0 And (contadorCaballoBlanco - decremento) >= 0 Then
            contadorCaballoBlanco = contadorCaballoBlanco - decremento
        End If

    End Sub
    'Devuelve la cantidad de caballos blancos que existen en el tablero
    Public Function CantidadCaballoBlanco() As Byte
        Return contadorCaballoBlanco
    End Function
    'Coloca una figura en la posición dada
    Public Overloads Sub cargarFigura(ByVal fil As Integer, ByVal col As Integer, ByVal figura As String)
        tablero(fil, col).figura = figura
        If (figura = piezas.blanco) Then
            Contador()
        End If
    End Sub
    Public Overloads Sub cargarFigura(ByVal pos As String, ByVal figura As String)
        Dim i As Integer
        Dim j As Integer
        i = CInt(pos) \ 10 'con la barra invertida se saca la division entera
        j = CInt(pos) Mod 10
        tablero(i, j).figura = figura
        If (figura = piezas.blanco) Then
            Contador()
        End If
    End Sub
    'Cuando cambia de posición la figura la ubica en la posición destino y la borra de la posición anterior. Sirve para el caballo negro
    Public Overloads Sub moverFigura(ByVal origenXY As String, ByVal DestinoXY As String, ByVal figura As String)
        For i As Integer = 1 To 8
            For j As Integer = 1 To 8
                If tablero(i, j).posicionXY = origenXY Then
                    tablero(i, j).figura = "2"
                End If
                If tablero(i, j).posicionXY = DestinoXY Then
                    tablero(i, j).figura = figura
                End If
            Next
        Next
    End Sub
    Public Overloads Sub moverFigura(ByVal tab As Tablero, ByVal origenXY As String, ByVal DestinoXY As String, ByVal figura As String)
        Dim io, jo, id, jd As Integer
        io = CInt(origenXY) \ 10
        jo = CInt(origenXY) Mod 10
        id = CInt(DestinoXY) \ 10
        id = CInt(DestinoXY) Mod 10
        tab.tablero(io, jo).figura = ""
        tab.tablero(id, jd).figura = figura
    End Sub
    'Pone todas las posiciónes en vacío y pone a cer el contador de caballos blancos
    Public Overloads Sub limpiarTablero()
        For i As Integer = 1 To 8
            For j As Integer = 1 To 8
                tablero(i, j).figura = piezas.vacio
            Next
        Next
        DesContador(CantidadCaballoBlanco)
        contadorCaballoNegro = False

    End Sub
    Public Overloads Sub limpiarTablero(ByVal pos As String)
        Dim fila As Integer
        Dim col As Integer
        fila = CInt(pos) \ 10
        col = CInt(pos) Mod 10
        tablero(fila, col).figura = piezas.vacio
        If tablero(fila, col).figura = piezas.blanco Then
            DesContador()
        End If
    End Sub




    Public ReadOnly Property ExistenCaballos() As Boolean
        Get
            Return contadorCaballoBlanco > 0
        End Get

    End Property


#End Region


#Region "busquedas"
#Region "Algoritmo A*"
    ''' <summary>
    ''' Devuelve el mejor camino que puede recorrer el caballo negro para comer todos los caballos blancos que se encuentran en el tablero.
    ''' Utiliza el algoritmo A*.
    ''' </summary>
    ''' <param name="tableroInicial">Tablero desde el cual se parte la búsqueda</param>
    ''' <param name="poscaballonegro">Posición en la que se encuentra el Caballo Negro en el Tablero inicial</param>
    ''' <returns>Devuelve un cola con el camino encontrado</returns>
    ''' <remarks></remarks>
    Public Function Aestrella(ByVal tableroInicial As Tablero, ByVal poscaballonegro As Integer) As Queue
        Dim Abiertos, Cerrados, Sucesores As ArrayList
        Dim f, g, h, movimiento, fila, col, ix, posCN, posCab, rep, iter As Integer
        Dim flag, b As Boolean
        Dim nodo(2), mejorNodo(2), nodoViejo(2), nodoCerrado(1), nodito(2) As Object
        Dim tabNew As Tablero
        Dim indiceA As Integer
        Dim indiceC As Integer
        Dim n As Integer
        Dim u, ui As Integer
        Dim fl As Boolean
        Abiertos = New ArrayList
        Cerrados = New ArrayList
        Sucesores = New ArrayList
        tabNew = New Tablero(tableroInicial)
        g = 0
        h = heuristica(tableroInicial, tableroInicial, poscaballonegro) 'Calcula la heurística del tablero inicial
        f = h + g
        nodo = New Object(2) {New Tablero(tableroInicial), f, New ArrayList}
        Abiertos.Add(nodo)                                              'Agrega el tablero inicial a la lista de nodos abiertos
        flag = False
        iter = 0
        While (Not flag) And (Abiertos.Count <> 0)                      'Evalua si ya no hay caballos blancos o si la lista de nodos abiertos está vacía
            mejorNodo = New Object(2) {Nothing, 0, New ArrayList}
            mejorNodo(1) = 400
            For k As Integer = 0 To (Abiertos.Count - 1)                'Busca el mejor nodo
                If Abiertos.Item(k)(1) < mejorNodo(1) Then
                    mejorNodo = New Object(2) {Nothing, 0, New ArrayList}
                    mejorNodo(0) = Abiertos(k)(0)
                    mejorNodo(1) = Abiertos(k)(1)
                    mejorNodo(2) = Abiertos(k)(2)
                    ix = k
                ElseIf Abiertos.Item(k)(1) = mejorNodo(1) And Not mejorNodo(0).ExistenCaballos Then     'Se asegura de que se hallan explotados todos los nodos con el mismo valor en caso de que se haya encontrado un nodo solución
                    mejorNodo = New Object(2) {Nothing, 0, New ArrayList}
                    mejorNodo(0) = Abiertos(k)(0)
                    mejorNodo(1) = Abiertos(k)(1)
                    mejorNodo(2) = Abiertos(k)(2)
                    ix = k
                End If
            Next
            Abiertos.RemoveAt(ix)                       'Se saca a mejor nodo de la lista de Abiertos
            nodoCerrado = New Object(1) {Nothing, 0}
            nodoCerrado(0) = mejorNodo(0)
            nodoCerrado(1) = mejorNodo(1)
            Cerrados.Add(nodoCerrado)                   'Se agrega a mejor nodo a la lista de nodos Cerrados
            If Not mejorNodo(0).ExistenCaballos Then    'Se fija si mejor nodo no es un nodo solución
                flag = True
            Else
                tabNew = New Tablero(mejorNodo(0))
                posCN = ObtenerPosCabNegro(tabNew)
                For op As Integer = 1 To 8              'Genera Sucesores de mejornodo (siempre y cuando no este en el camino);
                    Select Case op
                        Case 1
                            movimiento = movCaballo.operador1(posCN)    'Movimiento del caballo negro: 1 arriba y 2 a la izquierda
                        Case 2
                            movimiento = movCaballo.operador2(posCN)    'Movimiento del caballo negro: 2 arriba y 1 a la izquierda
                        Case 3
                            movimiento = movCaballo.operador3(posCN)    'Movimiento del caballo negro: 2 arriba y 1 a la derecha
                        Case 4
                            movimiento = movCaballo.operador4(posCN)    'Movimiento del caballo negro: 1 arriba y 2 a la derecha
                        Case 5
                            movimiento = movCaballo.operador5(posCN)    'Movimiento del caballo negro: 1 abajo y 2 a la derecha
                        Case 6
                            movimiento = movCaballo.operador6(posCN)    'Movimiento del caballo negro: 2 abajo y 1 a la derecha
                        Case 7
                            movimiento = movCaballo.operador7(posCN)    'Movimiento del caballo negro: 2 abajo y 1 a la izquierda
                        Case 8
                            movimiento = movCaballo.operador8(posCN)    'Movimiento del caballo negro: 1 abajo y 2 a la izquierda
                    End Select
                    nodo = New Object(2) {Nothing, 0, New ArrayList}
                    tabNew = New Tablero(mejorNodo(0))
                    If movimiento <> posCN Then                         'Se fija si la nueva posición no está fuera del tablero
                        fila = movimiento \ 10
                        col = movimiento Mod 10                         'Divide en fila y columna la nueva posición
                        If (tabNew.obtenerFigura(fila, col) = piezas.blanco) Then   'Si en la nueva posición había un caballo blanco los descuenta del total
                            tabNew.DesContador(tabNew)
                        End If
                        tabNew.moverFigura(posCN, movimiento, piezas.negro) 'Crea un nuevo nodo sucesor con la nueva posición del caballo negro
                        nodo(0) = tabNew
                        nodo(2).Add(mejorNodo(0))                           'Agrega a mejor nodo a la lista de los antecesores de en nodo sucesor
                        For ind As Integer = 0 To (mejorNodo(2).Count - 1)  'Agrega los antecesores de mejor nodo a los antecesores del nodo sucesor
                            nodo(2).Add(mejorNodo(2)(ind))
                        Next
                        rep = 0
                        b = False
                        While Not b And rep < nodo(2).Count                 'Se fija si el nodo sucesor no se a generado antes en el camino
                            b = (Funciones.compararTableros(nodo(0), nodo(2)(rep)))
                            rep = rep + 1
                        End While
                        If Not b Then                                       'En el caso de que no se haya generado antes el nodo lo agrega a la lista de sucesores
                            Sucesores.Add(nodo)
                        End If
                    End If
                    Application.DoEvents()
                    If FrmTablero.parar Then
                        FrmTablero.parar = False
                        FrmTablero.terminar = True
                        Exit While
                    End If
                Next
                n = 0
                While (n <= (Sucesores.Count - 1))                          'Para cada sucesor hacer
                    nodo = New Object(2) {Nothing, 0, New ArrayList}
                    nodoViejo = New Object(2) {Nothing, 0, New ArrayList}
                    nodo(0) = Sucesores(n)(0)
                    nodo(1) = Sucesores(n)(1)
                    nodo(2) = Sucesores(n)(2)
                    posCab = ObtenerPosCabNegro(nodo(0))
                    g = nodo(2).Count                                                 'Calcula g del sucesor basándose en la cantidad de antecesores que tiene, es decir, cuantas veces se aplicaron operadores
                    f = g + heuristica(mejorNodo(0), nodo(0), posCab)                 'f(sucesor):= g(sucesor) +h(sucesor);
                    nodo(1) = f
                    indiceA = -1
                    For k As Integer = 0 To (Abiertos.Count - 1)     'Buscar sucesor en Abiertos
                        If Funciones.compararTableros(Abiertos(k)(0), nodo(0)) Then
                            indiceA = k
                        End If
                    Next
                    indiceC = -1
                    If indiceA = -1 Then
                        For k As Integer = 0 To (Cerrados.Count - 1) 'Buscar sucesor en Cerrados
                            If Funciones.compararTableros(Cerrados(k)(0), nodo(0)) Then
                                indiceC = k
                            End If
                        Next
                    End If

                    If (indiceA > -1) Or (indiceC > -1) Then    'Si sucesor en Abiertos o Cerrados entonces

                        If indiceA > -1 Then                    'Si sucesor en Abiertos
                            nodoViejo(0) = Abiertos(indiceA)(0)
                            nodoViejo(1) = Abiertos(indiceA)(1)
                            nodoViejo(2) = Abiertos(indiceA)(2)
                            If nodo(1) <= nodoViejo(1) Then      'Si f(sucesor)<f(nodoviejo) entoces
                                Abiertos.RemoveAt(indiceA)      'Eliminar nodoviejo de abiertos
                                Abiertos.Add(nodo)
                                n = n + 1
                            Else                                'Sino()
                                Sucesores.RemoveAt(n)         'Eliminar sucesor;
                            End If                              'Fin si;
                        Else
                            If indiceC > -1 Then                'Si sucesor en Cerrados
                                nodoViejo(0) = Cerrados(indiceC)(0)
                                nodoViejo(1) = Cerrados(indiceC)(1)
                                If nodo(1) < nodoViejo(1) Then      'Si f(sucesor)<f(nodoviejo) entoces
                                    u = 0
                                    While u <= (Abiertos.Count - 1) 'Corta la rama del nodo cerrado que se eliminó
                                        nodito = New Object(2) {Nothing, 0, New ArrayList}
                                        nodito(0) = Abiertos(u)(0)
                                        nodito(1) = Abiertos(u)(1)
                                        nodito(2) = Abiertos(u)(2)
                                        While ui <= (nodito(2).Count - 1) And (Not fl)
                                            If (Funciones.compararTableros(nodito(2)(ui), nodoViejo(0))) Then
                                                Abiertos.RemoveAt(u)
                                                fl = True
                                            End If
                                            ui = ui + 1
                                        End While
                                        If Not fl Then
                                            u = u + 1
                                        End If
                                    End While
                                    Cerrados.RemoveAt(indiceC)      'Eliminar nodoviejo de cerrados
                                    Abiertos.Add(nodo)
                                    n = n + 1
                                Else                                'Sino()
                                    Sucesores.RemoveAt(n)          'Eliminar sucesor;
                                End If
                            End If                              'Fin si;
                        End If                                  'Fin si;
                    Else                                        'Sino()
                        Abiertos.Add(nodo)                      'agregar(sucesor, Abiertos);
                        n = n + 1
                    End If                                      'Fin Si;
                    Application.DoEvents()
                    If FrmTablero.parar Then
                        FrmTablero.parar = False
                        FrmTablero.terminar = True
                        Exit While
                    End If
                End While
                Sucesores = New ArrayList
            End If
        End While

        Dim q As Queue
        q = New Queue
        If flag Then
            For w As Integer = (mejorNodo(2).Count - 1) To 0 Step -1        'Agrega a una cola el camino obtenido
                q.Enqueue(mejorNodo(2)(w))
            Next
            q.Enqueue(mejorNodo(0))
            Return q
        Else
            Return q
        End If
    End Function
#End Region

#Region "Primero en Profundidad"
    ''' <summary>
    ''' Devuelve el primer camino que encuentra el algoritmo primero en profundidad para que el caballo negro pueda comer todos los caballos blancos que se encuentran en el tablero.
    ''' </summary>
    ''' <param name="tab">Tablero desde el cual se parte la búsqueda</param>
    ''' <param name="poscaballonegro">Posición del caballo negro en el tablero inicial</param>
    ''' <returns>Devuelve una cola con el camino encontrado</returns>
    ''' <remarks></remarks>
    Public Function primeroprof(ByVal tab As Tablero, ByVal poscaballonegro As Integer) As Queue
        Dim ListaNodos As ArrayList
        Dim nodoActual(1), nuevoNodo(1) As Object
        Dim flag, b As Boolean
        Dim movimiento, posCN, fila, col, rep As Integer
        Dim tabNew As Tablero
        nodoActual = New Object(1) {New Tablero(tab), New ArrayList}
        ListaNodos = New ArrayList
        ListaNodos.Add(nodoActual)
        flag = False
        While Not flag And ListaNodos.Count > 0
            nodoActual = New Object(1) {Nothing, New ArrayList}
            nodoActual(0) = ListaNodos(0)(0)
            nodoActual(1) = ListaNodos(0)(1)
            ListaNodos.RemoveAt(0)
            If Not nodoActual(0).ExistenCaballos Then
                flag = True
            Else
                For op As Integer = 1 To 8              'Genera Sucesores de nodoActual (siempre y cuando no este en el camino);
                    tabNew = New Tablero(nodoActual(0))
                    posCN = ObtenerPosCabNegro(tabNew)
                    Select Case op
                        Case 1
                            movimiento = movCaballo.operador8(posCN)    'Movimiento del caballo negro: 1 abajo y 2 a la izquierda
                        Case 2
                            movimiento = movCaballo.operador7(posCN)    'Movimiento del caballo negro: 2 abajo y 1 a la izquierda
                        Case 3
                            movimiento = movCaballo.operador6(posCN)    'Movimiento del caballo negro: 2 abajo y 1 a la derecha
                        Case 4
                            movimiento = movCaballo.operador5(posCN)    'Movimiento del caballo negro: 1 abajo y 2 a la derecha
                        Case 5
                            movimiento = movCaballo.operador4(posCN)    'Movimiento del caballo negro: 1 arriba y 2 a la derecha
                        Case 6
                            movimiento = movCaballo.operador3(posCN)    'Movimiento del caballo negro: 2 arriba y 1 a la derecha
                        Case 7
                            movimiento = movCaballo.operador2(posCN)    'Movimiento del caballo negro: 2 arriba y 1 a la izquierda
                        Case 8
                            movimiento = movCaballo.operador1(posCN)    'Movimiento del caballo negro: 1 arriba y 2 a la izquierda
                    End Select
                    nuevoNodo = New Object(1) {Nothing, New ArrayList}
                    tabNew = New Tablero(nodoActual(0))
                    If movimiento <> posCN Then                                     'Se fija si la nueva posición no está fuera del tablero
                        fila = movimiento \ 10
                        col = movimiento Mod 10                                     'Divide en fila y columna la nueva posición
                        If (tabNew.obtenerFigura(fila, col) = piezas.blanco) Then   'Si en la nueva posición había un caballo blanco los descuenta del total
                            tabNew.DesContador(tabNew)
                        End If
                        tabNew.moverFigura(posCN, movimiento, piezas.negro)       'Crea un nuevo nodo sucesor con la nueva posición del caballo negro
                        nuevoNodo(0) = tabNew
                        nuevoNodo(1).Add(nodoActual(0))                           'Agrega nodo actual a la lista de los antecesores de nuevo nodo
                        For ind As Integer = 0 To (nodoActual(1).Count - 1)       'Agrega los antecesores de nodo actual a los antecesores del nuevo nodo
                            nuevoNodo(1).Add(nodoActual(1)(ind))
                        Next
                        rep = 0
                        b = False
                        While Not b And rep < ListaNodos.Count
                            b = (Funciones.compararTableros(nuevoNodo(0), ListaNodos(rep)(0)))
                            If b Then
                                ListaNodos.RemoveAt(rep)
                            Else
                                rep = rep + 1
                            End If
                        End While
                        rep = 0
                        b = False
                        While Not b And rep < nuevoNodo(1).Count                 'Se fija si el nodo sucesor no se a generado antes en el camino
                            b = (Funciones.compararTableros(nuevoNodo(0), nuevoNodo(1)(rep)))
                            rep = rep + 1
                        End While
                        If Not b Then                                           'En el caso de que no se haya generado antes el nodo lo agrega a la pila de nodos
                            ListaNodos.Insert(0, nuevoNodo)
                        End If
                    End If
                    Application.DoEvents()
                    If FrmTablero.parar Then
                        FrmTablero.parar = False
                        FrmTablero.terminar = True
                        Exit While
                    End If
                Next
            End If
        End While
        Dim q As Queue
        q = New Queue
        If flag Then
            For w As Integer = (nodoActual(1).Count - 1) To 0 Step -1        'Agrega a una cola el camino obtenido
                q.Enqueue(nodoActual(1)(w))
            Next
            q.Enqueue(nodoActual(0))
            Return q
        Else
            Return q
        End If
    End Function
#End Region

#Region "Primero en Amplitud"
    ''' <summary>
    ''' Devuelve el camino más corto que puede recorrer el caballo negro para comer todos los caballos blancos que se encuentran en el tablero.
    ''' Utiliza el algoritmo Primero en Amplitudad.
    ''' </summary>
    ''' <param name="tab">Tablero desde el cual se parte la búsqueda</param>
    ''' <param name="poscaballonegro">Posición del caballo negro en el tablero inicial</param>
    ''' <returns>Devuelve una cola con el camino encontrado</returns>
    ''' <remarks></remarks>
    Public Function primeroamplitud(ByVal tab As Tablero, ByVal poscaballonegro As Integer) As Queue
        Dim ListaNodos As ArrayList
        Dim nodoActual(1), nuevoNodo(1) As Object
        Dim flag, b As Boolean
        Dim movimiento, posCN, fila, col, rep, iter As Integer
        Dim tabNew As Tablero
        nodoActual = New Object(1) {New Tablero(tab), New ArrayList}
        ListaNodos = New ArrayList
        ListaNodos.Add(nodoActual)
        flag = False
        iter = 0
        While Not flag And ListaNodos.Count > 0
            nodoActual = New Object(1) {Nothing, New ArrayList}
            nodoActual(0) = ListaNodos(0)(0)
            nodoActual(1) = ListaNodos(0)(1)
            ListaNodos.RemoveAt(0)
            If Not nodoActual(0).ExistenCaballos Then
                flag = True
            Else
                For op As Integer = 1 To 8              'Genera Sucesores de nodoActual (siempre y cuando no este en el camino);
                    tabNew = New Tablero(nodoActual(0))
                    posCN = ObtenerPosCabNegro(tabNew)
                    Select Case op
                        Case 1
                            movimiento = movCaballo.operador1(posCN)    'Movimiento del caballo negro: 1 arriba y 2 a la izquierda
                        Case 2
                            movimiento = movCaballo.operador2(posCN)    'Movimiento del caballo negro: 2 arriba y 1 a la izquierda
                        Case 3
                            movimiento = movCaballo.operador3(posCN)    'Movimiento del caballo negro: 2 arriba y 1 a la derecha
                        Case 4
                            movimiento = movCaballo.operador4(posCN)    'Movimiento del caballo negro: 1 arriba y 2 a la derecha
                        Case 5
                            movimiento = movCaballo.operador5(posCN)    'Movimiento del caballo negro: 1 abajo y 2 a la derecha
                        Case 6
                            movimiento = movCaballo.operador6(posCN)    'Movimiento del caballo negro: 2 abajo y 1 a la derecha
                        Case 7
                            movimiento = movCaballo.operador7(posCN)    'Movimiento del caballo negro: 2 abajo y 1 a la izquierda
                        Case 8
                            movimiento = movCaballo.operador8(posCN)    'Movimiento del caballo negro: 1 abajo y 2 a la izquierda
                    End Select
                    nuevoNodo = New Object(1) {Nothing, New ArrayList}
                    tabNew = New Tablero(nodoActual(0))
                    If movimiento <> posCN Then                         'Se fija si la nueva posición no está fuera del tablero
                        fila = movimiento \ 10
                        col = movimiento Mod 10                         'Divide en fila y columna la nueva posición
                        If (tabNew.obtenerFigura(fila, col) = piezas.blanco) Then   'Si en la nueva posición había un caballo blanco los descuenta del total
                            tabNew.DesContador(tabNew)
                        End If
                        tabNew.moverFigura(posCN, movimiento, piezas.negro) 'Crea un nuevo nodo sucesor con la nueva posición del caballo negro
                        nuevoNodo(0) = tabNew
                        nuevoNodo(1).Add(nodoActual(0))                           'Agrega nodo actual a la lista de los antecesores de nuevo nodo
                        For ind As Integer = 0 To (nodoActual(1).Count - 1)       'Agrega los antecesores de mejor nodo a los antecesores del nodo sucesor
                            nuevoNodo(1).Add(nodoActual(1)(ind))
                        Next
                        rep = 0
                        b = False
                        While Not b And rep < ListaNodos.Count
                            b = (Funciones.compararTableros(nuevoNodo(0), ListaNodos(rep)(0)))
                            rep = rep + 1
                        End While
                        If Not b Then
                            rep = 0
                            b = False
                            While Not b And rep < nuevoNodo(1).Count                 'Se fija si el nodo sucesor no se a generado antes en el camino
                                b = (Funciones.compararTableros(nuevoNodo(0), nuevoNodo(1)(rep)))
                                rep = rep + 1
                            End While
                        End If
                        If Not b Then                                       'En el caso de que no se haya generado antes el nodo lo agrega a la cola de nodos
                            ListaNodos.Add(nuevoNodo)
                        End If
                    End If
                    Application.DoEvents()

                    If FrmTablero.parar Then
                        FrmTablero.parar = False
                        FrmTablero.terminar = True
                        Exit While
                    End If
                Next
            End If
        End While
        Dim q As Queue
        q = New Queue
        If flag Then
            For w As Integer = (nodoActual(1).Count - 1) To 0 Step -1        'Agrega a una cola el camino obtenido
                q.Enqueue(nodoActual(1)(w))
            Next
            q.Enqueue(nodoActual(0))
            Return q
        Else
            Return q
        End If
    End Function
#End Region
#End Region
    Public Property ContadorCaballoNegro1() As Boolean
        Get
            Return contadorCaballoNegro
        End Get
        Set(ByVal value As Boolean)
            contadorCaballoNegro = value
        End Set
    End Property
    Public Function ObtenerPosCabNegro(ByVal tab As Tablero) As Integer
        For i As Integer = 1 To 8
            For j As Integer = 1 To 8
                If tab.obtenerFigura(i, j) = "1" Then
                    ObtenerPosCabNegro = CInt(CStr(i) + CStr(j))
                    Return ObtenerPosCabNegro
                End If
            Next
        Next
    End Function

End Class
